namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
    /// <summary>
    /// 1. Start at Service homepage
    /// 2. Select Cases
    /// 3. Click New button
    /// 4. Enter a title
    /// 5. Open lookup for Customer and double click an account
    /// 6. Open lookup for Subject and double click a subject
    /// 7. Save and Close
    /// </summary>

    public class CreateServiceCaseAccount : CrmWebTest
    {
        public void CreateServiceCaseAccount_PreWebTest(object sender, PreWebTestEventArgs e)
        {
			EntityRequest er = new EntityRequest();
			er.Type = EntityNames.Users;
			er.ReturnAs = EntityNames.Users;
			er.ParentID = EntityManager.Instance.OrgId;

			System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            
			EntityRequest AccountEr = new EntityRequest();
			AccountEr.Type = EntityNames.Accounts;
			AccountEr.ParentID = Guid.NewGuid();
			AccountEr.ReturnAs = EntityNames.Accounts;

			Props.Add(EntityNames.Accounts, new EntityRequest[] { AccountEr });

			er.Props = Props;

			System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

			user = (CRMEntity)Entities[EntityNames.Users];
			account = (CRMEntity)Entities[EntityNames.Accounts];

			er = new EntityRequest();
			er.Type = EntityNames.Subject;
			er.ParentID = EntityManager.Instance.OrgId;
			er.ReturnAs = EntityNames.Subject;

			Entities = EntityManager.Instance.GetEntities(er);

			subject = (CRMEntity)Entities[EntityNames.Subject];
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);
            ownerId = new Guid(user["systemuserid"]);
            customerId = new Guid(account["accountid"]);
            subjectId = new Guid(subject["subjectid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
        }
        
        public void CreateServiceCaseAccount_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            EntityManager.Instance.FreeEntity(subject);
            EntityManager.Instance.FreeEntity(account);
            EntityManager.Instance.FreeEntity(user);
        }

        public CreateServiceCaseAccount()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            GetContextHtml_Helper.Subject(out ctxt, out ctxt_formXml, out ctxt_formSubmitId);
            gridXml = GridXmlHelper.IncidentPageViewRefresh(-1, myIncidentView, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateServiceCaseAccount_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateServiceCaseAccount_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
			this.BeginTransaction("NavServiceCaseHomepage");

            cs_home_cases_aspx casesHome = new cs_home_cases_aspx(user);
            yield return (casesHome);

			this.EndTransaction("NavServiceCaseHomepage");
			
			this.BeginTransaction("CreateServiceCase");

            cs_cases_edit_aspx casesEdit = new cs_cases_edit_aspx(user);
            yield return (casesEdit);

            referer = casesEdit.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx f = new _forms_FormScript_js_aspx(user);
            f.etc = 112;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);
                        
            _controls_lookup_lookupsingle_aspx lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "BasicCustomer";
            lookup.objecttypes = "1,2";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            LookupService.LookupService lookupService = new LookupService.LookupService();
            CrmRequest lookupRequest;
            try
            {
                lookupService.RetrieveFormAssistantHtml("Category_Lookup", 1, "", "null", "BasicCustomer", "");
            }
            catch(crmException x)
            {
                lookupRequest = (CrmRequest)x.wtr;
                lookupRequest.Url = Utils.ReplaceServerName(lookupRequest.Url, user);

                string urlPath = lookupRequest.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                lookupRequest.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                lookupRequest.Headers.Add(headerItem);
                lookupRequest.Method = "Post";
            }

            _controls_lookup_lookupsubject_aspx lookupsubject = new _controls_lookup_lookupsubject_aspx(user);
            lookupsubject.Class = "BasicSubject";
            lookupsubject.objecttypes = "129";
            lookupsubject.browse = 0;
            lookupsubject.ShowNewButton = 1;
            lookupsubject.ShowPropButton = 1;
            lookupsubject.DefaultType = 0;
            yield return (lookupsubject);
            
            SubjectManager.SubjectManagerWebService smws = new SubjectManager.SubjectManagerWebService();
            CrmRequest wtr = null;
            try { smws.RetrieveTreeNodeHTML(new Guid(subject["subjectid"])); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);
                        
            // if the Help and Assistance Pane is on and the user tabs through the fields of the account
            // detail pane, they'll hit this (heavy) request when the tab into the 
            // primay contact field.
            if (ConfigSettings.Default.HelpAndAssistancePaneOn == "true")
            {
                RelatedInformation.RelatedInformation ri = new RelatedInformation.RelatedInformation();
                wtr = null;

                string formXml = ctxt_formXml;
                formXml = formXml.Replace("CUSTOMER_GUID", (account["accountid"]).ToUpper());
                formXml = formXml.Replace("SUBJECT_GUID", (subject["subjectid"]).ToUpper());
                formXml = formXml.Replace("USER_GUID", (user["systemuserid"]).ToUpper());
                try { ri.GetContextHtml(ctxt, formXml, ctxt_formSubmitId); }
                catch (crmException x)
                {
                    wtr = (CrmRequest)x.wtr;
                    wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
                }
                yield return (wtr);
            }

            casesEdit = new cs_cases_edit_aspx(user);
            
            casesEdit.crmFormSubmitXml = EntityXmlHelper.GetCreateIncidentXml(ownerId, 8, customerId, 1, subjectId, 129);
            rpcInfo = Utils.GenerateWRPCToken(cs_cases_edit_aspx.url, user, tokenKey);
            casesEdit.CRMWRPCToken = rpcInfo.token;
            casesEdit.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
            casesEdit.crmFormSubmitMode = 1;
            casesEdit.crmFormUserModified = true;
            casesEdit.crmFormSubmitObjectType = 112;
            casesEdit.crmFormSubmitOnline = 1;
            casesEdit.crmFormSubmitSecurity = 852023;
            yield return (casesEdit);

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            CrmRequest wtrRefresh = null;
            try { agws.Refresh(gridXml); }
            catch (crmException x)
            {
                wtrRefresh = (CrmRequest)x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
            }
            yield return (wtrRefresh);  

            this.EndTransaction("CreateServiceCase");
        }

        private static RelatedInformation.Context ctxt;
        private static string ctxt_formXml;
        private static string ctxt_formSubmitId;
		private const string newIdMarker = @"SetQueryString(sLocation,""id"",""";
        private CRMEntity user;
        private CRMEntity subject;
        private CRMEntity account;
        private string gridXml;
        private string crmServer;
        private string tokenKey;
        private static string myIncidentView = "00000000-0000-0000-00AA-000010001028";

        private Guid orgId;
        private Guid customerId;
        private Guid ownerId;
        private Guid subjectId;

        private string referer;
        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}